home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-09-14 | 30.3 KB | 954 lines | [TEXT/MPS ] |
- ;EASE$$$ READ ONLY COPY of file “sbarcdef.a”
- ; 1.1 CCH 12/22/1988 Added bug fix to "FrameCtl:" from 6.0.4 sources.
- ; 1.0 CCH 11/16/1988 Added to EASE.
- ; END EASE MODIFICATION HISTORY
- ;
- ;File SBarCDef.a
- ;--------------------------------------------------------------------------
- ;
- ; Standard ScrollBar Dial Definition Procedure for the
- ; MacIntosh Control Manager
- ;
- ; written by Andy Hertzfeld August, 1982
- ;
- ; (c) 1982-1986 by Apple Computer, Inc. All rights reserved.
- ;
- ; This file contains the control definition procedure
- ; that defines scrollBar-type dials.
- ;
- ; Modification History:
- ;
- ; 29-Aug-82 AJH Added "255" hiliting, non-rectangular indicators
- ; to ScrollBarProc
- ; 31-Aug-82 AJH Added hysterisis to scrollBar, rounding to value calculations
- ; 19-Sep-82 AJH Re-arranged ScrollBar proc, removed DragThumb
- ; 03-Oct-82 AJH Fixed bug in scrollBar positioning -- wasn't ctl relative
- ; 10-Oct-82 AJH Converted for QuickDraw Trap Interface
- ; 17-Oct-82 AJH Made controlProcs preserve A1
- ; 07-Nov-82 AJH Made wide scrollBars look better
- ; 11-Nov-82 AJH fixed thumb scaling problem in CalcIBox (subtract min)
- ; 14-Nov-82 AJH removed box in arrowBits
- ; 16-Nov-82 AJH Made branch tables offset based
- ; 28-Dec-82 AJH Put scrollBar definition proc in its own file
- ; 30-Dec-82 AJH Changed hystersis for thumbDrag to 24 pixels
- ; 30-Jul-83 SC Variant 1 for microsoft - no grey or elevator (Yuck)
- ; 04-Sep-83 AJH Made it respond to message 8 (just a stub)
- ; 08-Oct-83 AJH Changed rounding to fix "off by 1" bug
- ; 10-Nov-83 AJH Changed disabling -- don't fill with gray
- ; 11-Nov-83 AJH Made it redraw all if disabled
- ; 27-Dec-83 AJH Made min=max act disabled; added "254" hiliting
- ; 13-Apr-84 SC Replaced _EraseRgn with _FillRgn,white
- ; 11-Jan-85 JTC convert to MDS
- ; 14-Feb-85 JTC named rsrc.
- ; 18-Apr-85 EHB Eliminated useless framerects in DrawSBar
- ; 16-May-85 EHB Only return "254" if point in control!
- ; 29-Jul-85 EHB converted back to porkshop
- ;
- ;--Lonely Heiffer Release----------------------------------------------
- ;
- ; 28-Apr-86 DAF Workshop->MPW, added color support for Reno
- ;<C203/06Oct86> DAF Updated color support on nuMac to RGBColor
- ;<C529/14Dec86> DAF Fixed a trashed register
- ;<C700/26Jan87> DAF Universal defproc (Version 10)
-
-
- BLANKS ON
- STRING ASIS
-
- LOAD 'inc.sum.d'
- LOAD 'nEqu.d'
- INCLUDE 'colorEqu.a'
-
- CDEF1 PROC EXPORT
- ;
- ; FUNCTION ScrollBarProc( theControl: ControlHandle;
- ; message: INTEGER;
- ; param: LongInt): LongInt;
- ;
-
-
- ; And a stack frame definition
-
- SavePen EQU -20
- Align EQU -21 ;dead byte for alignment of stack frame
- IsColor EQU -22 ;is this a color system?
- IndicatorRect EQU -30
- AuxCtlHndl EQU -34 ;<DAF 28Apr86>
- AuxCtlPtr EQU -38 ;<DAF 28Apr86>
- SavFgCol EQU -44 ;<DAF 05Oct86>
- SavBkCol EQU -50 ;<DAF 05Oct86>
- TempCol EQU -56 ;<s557 d√b 08Aug88>
- FrameSize EQU -56 ;<s557 d√b 08Aug88>
- CtlHndl EQU 14 ;<DAF 28Apr86>
-
- ;
- ; Here is the dispatch table for the scrollBar definition procedure, which implements
- ; semi-Lisa style scrollBar type controls for the Mac toolBox. It shares a common
- ; dispatcher with the pushButton proc (see above)
- ;
- BRA.S @0
-
- DC.W 0
- DC.B 'CDEF'
- DC.W 1
- DC.W 10 ; version #
-
- @0
- LINK A6,#FrameSize ; set up a stack frame to address parameters
- MOVEM.L D3-D6/A1-A4,-(SP) ; save work registers
-
- ; test if the message is in range
-
- CMP.W #thumbCtlMsg,12(A6) ; compare to highest value
- BGT OORange ; skip it, it's too high
- CMP.W #drawCtlMsg,12(A6) ; compare to lowest value, too
- BMI OORange ;
-
- ;
- ; save the penState and set it our way
- ;
- PEA SavePen(A6) ; push pointer to savePenState
- _GetPenState ; remember current penState
- _PenNormal ; set the pen the way we want it
-
- ; Determine type of system. We need to know if we have color QuickDraw and a color
- ; window manager port.
-
- CMP.W #$3FFF,ROM85 ; do we have color QD?
- SLS IsColor(A6) ; set boolean depending on color or B&W system
- BHI.S @BWSys ; no, this system has B&W QD
-
- ; save the current port's colors
-
- MOVE.L GrafGlobals(A5),A0 ; get pointer to grafGlobals <C407/16Nov86> DAF
- MOVE.L thePort(A0),A0 ; get pointer to thePort <C407/16Nov86> DAF
-
- PEA SavFgCol(A6) ; save foreColor
- _GetForeColor ;
- PEA SavBkCol(A6) ; save backColor too
- _GetBackColor ;
-
- ;
- ; get the CtlAuxRec for this guy and lock it's colortable <DAF 26Apr86>
- ;
- CLR.L -(SP) ; return the handle here
- CLR.B -(SP) ; space for boolean func return
- MOVE.L CtlHndl(A6),-(SP) ; push the control handle
- PEA 6(SP) ; push a pointer to placeholder
- _GetAuxCtl ; get its auxRec
- ADDQ #2,SP ; don't need boolean result
- MOVE.L (SP)+,A0 ; get auxCtl handle
- MOVE.L (A0),A0 ; a pointer to the auxCtlRec
- MOVE.L ctlCTable(A0),A0 ; get colortable's handle
- MOVE.L A0,AuxCtlHndl(A6) ; save the handle
- _HLock ; lock the handle
- MOVE.L (A0),AuxCtlPtr(A6) ; save a pointer
-
- @BWSys
-
- ;
- ; fetch the parameters into registers
- ;
- LEA 8(A6),A0 ; get ptr to first parameter
- MOVE.L (A0)+,D3 ; get param in D3
- MOVE.W (A0)+,D0 ; get message
- MOVE.L (A0)+,A3 ; get the control handle
- MOVE.W (A0)+,D6 ; get selection index
- CLR.L (A0) ; clear out function result
- MOVE.L (A3),A0 ; get control pointer in A0
- ;
- ; case out on the message number
- ;
- ADD D0,D0 ; double for word index
- LEA GoScrollBar,A1 ; get table address
- ADD 0(A1,D0),A1 ; compute dispatch address
- JSR (A1) ; dispatch to appropriate routine
- ;
- ; restore original pen state
- ;
- PEA SavePen(A6) ; push savePenState
- _SetPenState ; restore original pen state
-
- ;
- ; clean up color stuff <DAF 28Apr86>
- ;
- TST.B IsColor(A6) ;
- BEQ.S @NoColor1 ; if on B&W, then skip
-
- MOVE.L AuxCtlHndl(A6),A0 ; unlock the CDEF
- _HUnlock
- PEA SavFgCol(A6) ;
- _RGBForeColor ;
- PEA SavBkCol(A6) ;
- _RGBBackColor ;
-
- @NoColor1
-
- ;
- ; we're done -- restore registers and return to caller
- ;
-
- OORange ; 'Out Of Range, of course'
- MOVEM.L (SP)+,D3-D6/A1-A4 ; restore work registers
- UNLK A6 ; unlink stack frame
- TenBytExit MOVE.L (SP)+,A0 ; get return address
- ADD #12,SP ; strip parameters
- JMP (A0) ; return to caller
-
- GoScrollBar
- DC.W DrawSBar-GoScrollBar ; draw is message 0
- DC.W HitSBar-GoScrollBar ; hit test is message 1
- DC.W CalcSBar-GoScrollBar ; calc regions is message 2
- DC.W InitSBar-GoScrollBar ; allocate indicator region (3)
- DC.W DispSBar-GoScrollBar ; de-allocate indicator region (4)
- DC.W MoveSBar-GoScrollBar ; message 5 is move indicator call (5)
- DC.W ThumbSBar-GoScrollBar ; message 6 is thumb dragging
-
- ;
- ; 16 wide by 16 high little bitMaps used for scrollBar arrows
- ;
- ; (the comments as to which are left/right or up/down may lie)
- ;
-
- ;
- ; Left Arrow BitMap
- ;
- LArrowData
- DC.W $FFFF,$8081,$80C1,$80A1,$8F91,$8809,$8805,$8803
- DC.W $8805,$8809,$8F91,$80A1,$80C1,$8081,$8001,$FFFF
- LArrowMask
- DC.W $FFFF,$8081,$80C1,$80E1,$8FF1,$8FF9,$8FFD,$8FFF
- DC.W $8FFD,$8FF9,$8FF1,$80E1,$80C1,$8081,$8001,$FFFF
-
- ;
- ; Right Arrow BitMap
- ;
- RArrowData
- DC.W $FFFF,$8101,$8301,$8501,$89F1,$9011,$A011,$C011
- DC.W $A011,$9011,$89F1,$8501,$8301,$8101,$8001,$FFFF
- RArrowMask
- DC.W $FFFF,$8101,$8301,$8701,$8FF1,$9FF1,$BFF1,$FFF1
- DC.W $BFF1,$9FF1,$8FF1,$8701,$8301,$8101,$8001,$FFFF
-
- ;
- ; Up Arrow BitMap
- ;
- UArrowData
- DC.W $FFFF,$8001,$8001,$8FE1,$8821,$8821,$8821,$F83D
- DC.W $A009,$9011,$8821,$8441,$8281,$8101,$8001,$FFFF
- UArrowMask
- DC.W $FFFF,$8001,$8001,$8FE1,$8FE1,$8FE1,$8FE1,$FFFD
- DC.W $BFF9,$9FF1,$8FE1,$87C1,$8381,$8101,$8001,$FFFF
- ;
- ; Down Arrow BitMap
- ;
- DArrowData
- DC.W $FFFF,$8001,$8101,$8281,$8441,$8821,$9011,$A009
- DC.W $F83D,$8821,$8821,$8821,$8FE1,$8001,$8001,$FFFF
- DArrowMask
- DC.W $FFFF,$8001,$8101,$8381,$87C1,$8FE1,$9FF1,$BFF9
- DC.W $FFFD,$8FE1,$8FE1,$8FE1,$8FE1,$8001,$8001,$FFFF
-
-
-
- ; SetUpColor takes a window part identifier in D0, finds the corresponding
- ; part in the AuxWinTable (the part code is in the .value field) and returns
- ; a pointer to its RGB on the stack. If the requested part is not found,
- ; the first color table element is used (I'd use frameColor, but that might
- ; not be there!). Trashes A0/D0.
-
- SetUpColor
- MOVE.L D1,-(SP) ; save a register
- MOVE.L AuxCtlPtr(A6),A0 ; get the color table pointer
- MOVE.W CTSize(A0),D1 ; get the color table size
- MULU #8,D1 ; convert to color table index
- LegalIndex
- CMP.W CTTable+value(A0,D1),D0 ; is this the one?
- BEQ.S FoundIt ; if equal, then done
- SUB.W #8,D1 ; try the previous one
- BGE.S LegalIndex ; loop while index positive
- MOVEQ #0,D1 ; OK, use the first one
- FoundIt
- LEA CTTable+rgb(A0,D1),A0 ; get the address of the color to use
- MOVE.L A0,D0 ; we'll need A0 in a second
- MOVE.L (SP)+,D1 ; restore the register
- MOVE.L (SP)+,A0 ; get the return address
- MOVE.L D0,-(SP) ; push the rgb addr on the stack
- JMP (A0) ; return to caller
-
-
- ;
- ; DrawSBar draws a scroll bar as specified by the controlHandle in A3. D3 has the
- ; desired "hilite" area code.
- ;
- DrawSBar
-
- ;
- ; Set up fore- and backcolors (since they rarely change)
- ; {this could almost happen in the prologue!}
- ;
-
- TST.B IsColor(A6) ; are we on a color system?
- BEQ.S @NoColor2 ; if on B&W, then skip
-
- MOVEQ #cFrameColor,D0 ; get the index of the color to set
- BSR.S SetUpColor ; get this color on the stack
- _RGBForeColor ; and set it
- MOVEQ #cBodyColor,D0 ;
- BSR.S SetUpColor ;
- _RGBBackColor
-
- MOVE.L (A3),A0 ; get control pointer in A0 again since color calls killed it <C529/14Dec86> DAF
-
- @NoColor2 ; END OF A COLOR-ONLY SECTION
-
- ;
- ; Figure out if the scroll bar is horizontal or vertical and handle each
- ; case separately. see if its more horizontal or vertical -- A0 points to the
- ; rect to be tested. D0 returns 0 to select vertical and two to select horizontal.
- ; After we know which axis, draw the arrows.
- ;
- TST.B ContrlVis(A0) ; is it visible?
- BEQ StubSBar ; if not, don't draw
-
- ; if it was disabled, draw the whole thing
-
- CMP.B #$FF,D3 ; disabled part code?
- BNE.S @0 ; if not, skip
- MOVEQ #0,D3 ; if so, draw all
- @0
- MOVE.B ContrlHilite(A0),D4 ; get current hilite in register
- BSR GetTCtlRect ; copy the control rect into tempRect
- BSR TestHV ; get horizontal/vertical index in D0
- ;
- ; adjust for 1st arrow (if we're supposed to)
- ;
- MOVE.W Top(A1,D0),D1 ; get vertical coordinate
- ADD D2,D1 ; compute bottom
- MOVE.W D1,Bottom(A1,D0) ; update bottom
- LEA RArrowData,A1 ; point to right arrow bitMap
- MOVEQ #inUpButton,D1 ; signal 1st arrow
- ;
- MOVEM D0/D2,-(SP) ; remember hv selector
- ;
- BSR.S ShouldIDraw ; test hilite to see if we should draw
- BNE.S SkipUp
- BSR DrawArrowBox ; draw the arrow box
- ;
- ; now do the other arrow
- ;
- SkipUp
- BSR GetTCtlRect ; copy bounding rect into tempRect
- MOVEM (SP)+,D0/D2 ; restore hv selector
- ;
- ; adjust rect for 2nd arrow
- ;
- MOVE Bottom(A1,D0),D1 ; get bottom coordinate
- SUB D2,D1 ; compute top
- MOVE D1,Top(A1,D0) ; adjust box top
- LEA LArrowData,A1 ; point to 1st set of bitMaps
- MOVEQ #inDownButton,D1 ; signal in 2nd arrow
- ;
- BSR.S ShouldIDraw ; dont't draw if we done have to
- BNE.S SkipDown
- BSR DrawArrowBox ; draw the arrow box
-
- ;
- ; paint the body of the scrollBar light gray
- ;
- SkipDown
- ;
- CMP #1,D6 ; flavor one has no grey
- BEQ FrameCtl
-
- MOVE.W #inThumb,D1 ; get thumb part code
- BSR.S ShouldIDraw ; draw it?
- BNE.S StubSBar ; don't need to frame scrollbar <EHB 4-18-85>
-
- BSR GetTCtlRect ; get control bounding rectangle
- MOVE.L A1,-(SP) ; push tempRect
- BSR GetLtGray ; get pointer to light gray pattern
- MOVE.L A0,-(SP) ; push it
- ;
- BSR.S IsDisabled ; is it disabled?
- BNE.S @0 ; if not, skip
-
- MOVE.L (A5),A0 ; get grafGlobals
- LEA White(A0),A0 ; get address of white pattern
- MOVE.L A0,(SP) ; use it
- @0
- LEA TempRect,A1 ; get tempRect pointer back
- MOVE.L A1,A0 ; put in A0 for TestHV
- BSR.S TestHV ; get h/v index
- SWAP D2 ; get width in high part
- MOVE.W #1,D2 ; get 1 in low part
- TST.W D0 ; which dimension?
- BEQ.S @1 ; skip correction if vertical
-
- SWAP D2
-
- @1 MOVE.L A1,-(SP) ; push a pointer to the rectangle
- MOVE.L D2,-(SP) ; push inset factor
-
- _InsetRect ; inset it appropriately
- _FillRect ; paint the body gray
- BRA.S DoIndicator ; go plot the indicator
- ;
- ; Utility ShouldIDraw -- to test when to skip drawing a part of the scrollBar.
- ; On entry, D3 has parameter indicating part that needs drawing while D1 holds
- ; the part we are about to draw. If D3 is zero, always draw it. Otherwise,
- ; draw only if it matches. Returning 0 in the Z-flag means you should draw
- ;
- ShouldIDraw
- TST D3 ; examine the parameter
- BEQ.S StubSBar ; its zero so don't test further
- CMP D1,D3 ; the right part
- StubSBar RTS ; the z-flag has the answer
-
- ; IsDisabled is a utility to check to see if a scrollBar is disabled or not.
- ; It returns with the z-flag set if it is disabled
-
- IsDisabled
- MOVE.L (A3),A0 ; get sBar pointer
- MOVE.B ContrlHilite(A0),D0 ; get the hilite parameter
-
- ADDQ.B #1,D0 ; was it 255?
- BEQ.S @0 ; if so, its disabled
- ADDQ.B #1,D0 ; how about 254?
- BEQ.S @0 ; if so, its disabled also
-
- MOVE.W ContrlMin(A0),D0 ; get the min
- CMP.W ContrlMax(A0),D0 ; same as the max?
- @0
- RTS ; return to caller with z-flag result
-
- ;
- ; Check the hilite state. If the control is inactive (hilite = 255), don't draw
- ; the indicator at all.
- ;
- DoIndicator
-
- TST.B IsColor(A6) ; are we on a color system?
- BEQ.S @NoColor3 ; if on B&W, then skip
-
- MOVEQ #cElevatorColor,D0 ; set up this as the background color <DAF 28Apr86>
- BSR SetUpColor ;
- _RGBBackColor
- @NoColor3 ; END OF A COLOR-ONLY SECTION
-
- BSR CalcIBox ; calculate the indicator box
- BSR.S IsDisabled
- BEQ.S FrameCtl ; if so, skip
-
- MOVE.L ContrlData(A0),-(SP) ; push indicator region handle
- MOVE.L (SP),-(SP) ; we need it again
- MOVE.L GrafGlobals(A5),A0 ; our erase rect
- PEA white(A0)
- _FillRgn ; paint it white
- _FrameRgn ; and frame it
- ;
- ; frame the whole rect
- ;
- FrameCtl
- TST.B IsColor(A6) ; if not in color... <s557 d√b 08Aug88>
- BEQ.S @NoColor4 ; <s557 d√b 08Aug88>
- PEA TempCol(A6) ; Avoid QD's contrast mapping <s557 d√b 08Aug88>
- MOVE.L (SP),-(SP) ; by explicitly having the same <s557 d√b 08Aug88>
- _GetForeColor ; background and foreground. <s557 d√b 08Aug88>
- _RGBBackColor ; <s557 d√b 08Aug88>
- @NoColor4 ; <s557 d√b 08Aug88>
-
- MOVE.L (A3),A0
- PEA ContrlRect(A0) ; push pointer to scrollBar rect
- _FrameRect ; frame it
- ;
- ; all done drawing the scroll bar
- ;
- RTS
-
- ;
- ; TestHV is a utility that determines if the rectangle pointed to by A0 is more horizontal
- ; or vertical. Return 0 in D0 if its more vertical and 2 if its more horizontal.
- ; This routine trashes D1. The result is also reflected in the condition code.
- ; It also returns the width/height of the minor dimension in D2.
- ;
- TestHV
- MOVE Bottom(A0),D0
- SUB Top(A0),D0 ; get height
- MOVE Right(A0),D1
- SUB Left(A0),D1 ; get width
-
- CMP D0,D1 ; compare width and height
- BGT.S @1 ; branch it width is greater
-
- MOVE D1,D2 ; horizontal in D2
- MOVEQ #0,D0 ; signal its vertical
- RTS
-
- @1 MOVE D0,D2 ; vertical in D2
- MOVEQ #2,D0 ; signal its horizontal
- RTS
- ;
- ; DrawArrowBox is a routine that clears and frames an arrow box and then blits
- ; across the appropriate arrow (looks at hilite state). On entry, TempRect has the
- ; box for the arrow, D0 has h/v selector, D1 has left/right selector,A1 points to the
- ; arrow bitMap, A3 has the control handle.
- ;
- DrawArrowBox
- MOVE.L (A3),A0 ; get the control pointer
- CMP.B ContrlHilite(A0),D1 ; should it be hilited?
- BNE.S @1 ; if not, skip
- ADD #32,A1 ; if so, bump to hilite mask
- ;
- ; adjust bitMap for vertical or horizontal arrows
- ;
- @1 TST D0
- BNE.S @2
- ADD #128,A1 ; bump to horizontal
- ;
- ; plot the arrow
- ;
- @2 CLR D0 ; mode is srcCopy
- BSR.S PlotSymbol ; plot the bitmap in the tempRect box
- ;
- ; Now frame the box and we're done! (bitmap has rect EHB)
- ;
- ; PEA TempRect ; push the rectangle <EHB 4-18-85>
- ; _FrameRect ; frame it and we're done <EHB 4-18-85>
- SBarStub
- RTS
- ;
- ; PlotSymbol -- plot the little 16 by 16 symbol bitmap pointed to by A1 into the rectangle
- ; pointed held in TempRect. D0 holds the mode.
- ;
- PlotSymbol
- LEA IconBitMap,A0 ; get pointer to source bitmap
- MOVE.L A1,(A0)+ ; update base address of bitMap
- MOVE #2,(A0)+ ; update rowBytes
- CLR.L (A0)+ ; topLeft is zero, zero
- MOVE.L #$00100010,(A0) ; adjust boundsRect
- ;
- ; push parameters for CopyBits call to transfer arrow bitMap
- ;
- PEA IconBitMap ; push pointer source bitmap
- MOVE.L (SP),A0 ; remember in A0, too
- MOVE.L GrafGlobals(A5),A1 ; get lisaGraf global baseaddress
- MOVE.L THEPORT(A1),A1 ; get thePort
- PEA PORTBITS(A1) ; that's the destination bitmap
- ;
- PEA BOUNDS(A0) ; boundsRect of bitmap is source
- PEA TempRect ; tempRect is the destination
- MOVE.W D0,-(SP) ; theMode is in D0
- CLR.L -(SP) ; no mask region
- ;
- ; transfer the bitMap (stretching as necessary...)
- ;
- _CopyBits ; let Bill stretch those bits
- RTS ; return to caller
- ;
- ; CalcIBox is the crucial routine that computes the position of the top/left of the
- ; thumb by scaling the control's value according to its range and the screen area.
- ; Return the rectangle in IndicatorRect(A6). It expects that A3 will hold the
- ; control handle as usual
- ;
- CalcIBox
- MOVE D3,-(SP) ; preserve D3
- LEA IndicatorRect(A6),A1 ; get address of indicator rectangle
- BSR.S GetCtlRect ; first set it to control bounding rect
- ;
- MOVEQ #0,D1 ; clear out high part of D1
- MOVE.L (A3),A0 ; get pointer to control
- LEA ContrlRect(A0),A0 ; get pointer to the bounding rectangle
- BSR.S TestHV ; get h/V selector index in D0
- ; ???? was .S
- MOVE D2,D3 ; keep minor dimension in D3
- ;
- ; compute control screen area in relevant dimension
- ;
- MOVE Bottom(A0,D0),D1 ; get logical "bottom"
- SUB Top(A0,D0),D1 ; compute "height"
- SUB D2,D1 ; discount arrow box
- SUB D2,D1 ; discount other one, too
- SUB D2,D1 ; and the indicator
- ;
- ; compute "screenSize times value"
- ;
- MOVE.L (A3),A0 ; get control pointer
- MOVE.W ContrlValue(A0),D2 ; get current value
- SUB.W ContrlMin(A0),D2 ; get delta from min
- MULU D2,D1 ; compute value*screensize
- ;
- ; compute size of logical space
- ;
- MOVE ContrlMax(A0),D2 ; get max
- SUB ContrlMin(A0),D2 ; compute size of space
- BEQ.S Scale0 ; dont divide by 0
- ;
- ; perform the scaling
- ;
- DIVU D2,D1 ; compute where iBox should go
- BSR RoundOff ; round off D1
- ADD D3,D1 ; skip over arrow box
- ;
- ; update indicator rect to correct position
- ;
- UpdateIRect
- LEA IndicatorRect(A6),A1 ; get pointer to rect
- ADD Top(A1,D0),D1 ; compute the logical "top"
- MOVE D1,Top(A1,D0) ; update it
- ADD D3,D1 ; bump to "bottom"
- MOVE D1,Bottom(A1,D0) ; update "bottom"
- ;
- EOR #2,D0 ; flip to minor dimension
- ADDQ #1,Top(A1,D0) ; inset logical "left"
- SUBQ #1,Bottom(A1,D0) ; inset logical "right"
- ;
- ; set up the indicator region
- ;
- MOVE.L ContrlData(A0),-(SP) ; push indicator region handle
- MOVE.L A1,-(SP) ; push rect ptr
- _RectRgn ; make a rectangular region
- ;
- CalcIDone MOVE (SP)+,D3 ; restore D3
- RTS
- ;
- ; if min = max, pin at top
- ;
- Scale0 MOVE D3,D1
- BRA.S UpdateIRect
- ;
- ; GetCtlRect is a code saving utility that copies the bounding rectangle of the control
- ; whose handle is in A3 into the rectangle pointed to by A1. This routine blows
- ; A0 but preserves A1. GetTCtlRect is an alternative entry used to save code
- ;
- GetTCtlRect LEA TempRect,A1
- GetCtlRect MOVE.L (A3),A0 ; get pointer to control
- LEA ContrlRect(A0),A0 ; get pointer to bounding rect
- MOVE.L (A0),(A1) ; copy topLeft
- MOVE.L 4(A0),4(A1) ; copy botRight
- NoSBarHit
- RTS
- ;
- ; HitSBar is the hit test routine for the scroll bar definition routine. It classifies
- ; the position of the mouse passed in D3
- ;
- HitSBar
- MOVE.B ContrlHilite(A0),D4 ; get hilite state <EHB 16-May-85
- CMP.B #254,D4 ; 254 hiliting? <EHB 16-May-85>
- BEQ.S @0 ; => yes, do hit-test <EHB 16-May-85>
-
- BSR IsDisabled ; otherwise disabled? <EHB 16-May-85>
- BEQ.S NoSBarHit ; => yes, return with 0 <EHB 16-May-85>
- @0
- LEA ContrlRect(A0),A4 ; keep rect pointer in A4
- CLR.W -(SP) ; make room for function result
- MOVE.L D3,-(SP) ; push the point
- MOVE.L A4,-(SP) ; push address of rect
- _PtInRect ; in the rectangle?
- TST.B (SP)+ ; examine result
- BEQ.S NoSBarHit ; if not, we're done
-
- ; check for 254 hiliting
-
- ADDQ.B #2,D4 ; 254 hiliting? <EHB 16-May-85>
- BEQ.S Return254 ; => yes, return 254 <EHB 16-May-85>
-
- ; its in the rect, so classify if in upButton,downButton,pageUp,pageDown or thumb
-
- BSR.S NormalizePt ; swap relevant coordinate into low part
- ; ; and set up D0,D2
- ; see if its in the top button
- ;
- @1 MOVE D3,D1 ; get copy of mousePoint
- SUB 0(A4,D0),D1 ; subtract rectangle top
- CMP D2,D1 ; is it within width of the top?
- BGT.S @2 ; it not, go check bottom
- MOVEQ #inUpButton,D0 ; classify it
- BRA.S UpdateResult ; all done
- ;
- ; see if its in the bottom button
- ;
- @2 MOVE 4(A4,D0),D1 ; get bottom
- SUB D3,D1 ; get distance from bottom
- CMP D2,D1 ; is it in it?
- BGT.S CheckInd ; if not, go check indicator
- ;
- MOVEQ #inDownButton,D0
- UpdateResult
- MOVE D0,22(A6) ; return result
- RTS
- Return254
- MOVE #254,D0
- BRA.S UpdateResult
- ;
- ; its not in either button so it must be the thumb or one of the page areas. Check
- ; for the thumb first
- ;
- CheckInd
- CMP #1,D6 ; for flavor one don't test
- BEQ.S NoSBarHit
-
- BSR CalcIBox ; calculate the indicator rectangle
- BSR.S NormalizePt ; restore back to normal point
- CLR.W -(SP) ; make space for boolean result
- MOVE.L D3,-(SP) ; push the point
- MOVE.L (A3),A0
- MOVE.L ContrlData(A0),-(SP) ; push the indicator region
- _PtInRgn ; is the mouse in the indicator?
- TST.B (SP)+ ; (..the suspense builds...)
- BEQ.S CheckPage ; branch if its not in the indicator
- ;
- ; its in the thumb so report that to the application
- ;
- MOVE #inThumb,D0 ; get result
- BRA.S UpdateResult ; all done -- go update result
-
- ;
- ; it must be in one of the two page areas. Determine which one by looking at the
- ; midPoint of the indicator's bounding rectangle.
- ;
- CheckPage
- BSR.S NormalizePt ; normalize (get interesting low word)
- MOVE.L (A3),A0 ; get control pointer
- MOVE.L ContrlData(A0),A0 ; get region handle
- MOVE.L (A0),A0 ; get region pointer
- LEA RgnBBox(A0),A0 ; point to the region bounding box
- ;
- ; determine midpoint
- ;
- MOVE Bottom(A0,D0),D1 ; get logical bottom
- SUB Top(A0,D0),D1 ; get logical height
- LSR #1,D1 ; divide by 2
- ADD Top(A0,D0),D1 ; add to get the midpoint
- ;
- ; at this point, D1 has the midpoint in the important dimension. Compare with the
- ; mouse point to decide if its page up or down.
- ;
- CMP D1,D3 ; compare mousePt with midPoint
- BLT.S PageItUp ; if above its the logical "top"
- MOVEQ #inPageDown,D0 ; set result code
- BRA.S UpdateResult ; all done -- go update result
- PageItUp MOVEQ #inPageUp,D0 ; set result code
- BRA.S updateResult ; all done
- ;
- ; NormalizePt takes a rect pointer in A4 and a point in D3 and swaps the points
- ; coordinates according to the relevant dimensions
- ;
- NormalizePt
- MOVE.L A4,A0 ; get rect pointer in A0
- BSR TestHV ; get horizontal vertical offset
- BNE.S @1 ; if horizontal, skip
- SWAP D3 ; its vertical so get y in low part
- @1 RTS ; all done
-
- ;
- ; CalcSBar returns the bounding region of the scroll bar. D3 holds the region parameter.
- ; If the high bit of D3 is set, return the indicator region, other return the entire
- ; bounding region
- ;
- CalcSBar
- TST.L D3 ; indicator or body?
- BMI.S GetIndRgn ; if negative, go get indicator
- MOVE.L D3,-(SP) ; push the region handle
- PEA ContrlRect(A0) ; push rectangle pointer
- _RectRgn ; return a rectangular region
- RTS ; all done!
- ;
- ; the indicator region was requested so copy the one in the dataHandle
- ;
- GetIndRgn
- BSR CalcIBox ; calculate indicator region
- MOVE.L (A3),A0 ; get pointer to control
- MOVE.L ContrlData(A0),-(SP) ; push indicator region
- MOVE.L D3,-(SP) ; push result region
- CLR.B (SP) ; clear out high byte
- _CopyRgn ; clone the region
- ;
- ; set the pattern for dragging
- ;
- BSR.S GetLtGray ; get pointer to light gray
- MOVE.L (A0)+,DragPattern ; update the drag pattern
- MOVE.L (A0),DragPattern+4 ; update the drag pattern
- RTS
- ;
- ; GetLtGray is a short utility that get a pointer to a lightGray pattern from
- ; the resource manager.
- ;
- GetLtGray
- SUBQ #4,SP ; make room for result
- MOVE.W #SBarPatID,-(SP) ; push resource ID
- _GetPattern ; get the pattern
- MOVE.L (SP)+,A0 ; get pattern handle
- MOVE.L (A0),A0 ; get pattern ptr
- RTS
-
- ;
- ; handle the "position yourself" message by calling figuring out the new value and
- ; calling SetCtlValue. D3 holds the amount to move by.
- ;
- MoveSBar
- MOVE.L ContrlData(A0),A0 ; get handle of indicator region
- MOVE.L (A0),A0 ; get a pointer to it
- LEA RgnBBox(A0),A4 ; get pointer to the bounding rect
- ;
- ; figure out new position by adding topLeft of current position to offset
- ;
- ADD Left(A4),D3 ; add the x coordinates
- SWAP D3 ; get y in low word
- ADD Top(A4),D3 ; add the y coordinates
- ;
- ; select the relevant dimension and get it into the low word of D3
- ;
- MOVE.L (A3),A0 ; get the control pointer
- LEA ContrlRect(A0),A0 ; get the bounding rectangle
- BSR TestHV ; get h/v index
- BEQ.S @1 ; if its y, we're cool
- SWAP D3 ; get x into D3
- ;
- ; determine amount of screen area devoted to the scrollBar
- ;
- @1 SUB Top(A0,D0),D3 ; make size ctl-relative
- SUB D2,D3 ; subtract arrow offset
- ;
- MOVE Bottom(A0,D0),D1 ; get logical bottom
- SUB Top(A0,D0),D1 ; compute logical height
-
- SUB D2,D1 ; compute active area
- SUB D2,D1
- SUB D2,D1
- MOVE D1,D2 ; get answer in D2
- ;
- ; compute range of logical values: controlMax - controlMin
- ;
- MOVE.L (A3),A0 ; get control pointer
- MOVE ContrlMax(A0),D1 ; get max value
- SUB ContrlMin(A0),D1 ; compute range
- ;
- ; compute position*logical range/physical range
- ;
- MULU D3,D1 ; D3 has current position
- DIVU D2,D1 ; divide by physical range
- BSR.S RoundOff ; round to nearest integer
- ;
- ; at this point D1 has the value so set it, after offsetting by the minimum
- ;
- ADD.W ContrlMin(A0),D1 ; offset by minimum
- MOVE.L A3,-(SP) ; push control handle
- MOVE.W D1,-(SP) ; push the new value
- _SetCtlValue ; go set the new value
- RTS ; all done!
- ;
- ; InitSBar gets called when the scroll bar is allocated. It allocates an empty region
- ; to use as the indicator region
- ;
- InitSBar SUBQ #4,SP
- _NewRgn ; get a new region on the stack top
- MOVE.L (A3),A0 ; get control pointer
- MOVE.L (SP)+,ContrlData(A0) ; remember new region in control data
- RTS
- ;
- ; DispSBar de-allocates the region used for the indicator
- ;
- DispSBar MOVE.L ContrlData(A0),A0 ; get handle of indicator region
- _DisposHandle ; dispose of it
- RTS
- ;
- ; Utility RoundOff -- RoundOff the number in D1 to the nearest integer. The remainder
- ; from dividing by D2 is in the high part of the word.
- ;
- RoundOff MOVE.W D0,-(SP) ; preserve D0
- MOVE D2,D0 ; get old divisor
- LSR #1,D0 ; divide by 2
- SWAP D1 ; get remainder
- CMP D0,D1 ; compare remainder with 1/2 divisor
- BLE.S TruncateIt ; if smaller, we're done
- SWAP D1 ; get normal D1 back
- ADDQ #1,D1 ; round up
- ;
- RoundDone
- MOVE.W (SP)+,D0 ; restore D0
- RTS
- ;
- ; no need to round up so just truncate it
- ;
- TruncateIt
- SWAP D1 ; restore quotient
- BRA.S RoundDone ; all done with roundOff
-
- ;
- ; ThumbSBar receives the "drag thumb message for the scroll bar. On entry, D3 points
- ; to a structure that contains the starting point, it returns with pointers to
- ; the bounds and slopRect and the axis parameter
- ;
- ; Local Variable Equates
- ;
- BRect EQU 0 ; boundsRect
- SRect EQU 8 ; slopRect
- TAxis EQU 16 ; axis
- ;
- ThumbSBar
- MOVE.L D3,A4 ; keep pointer to parameter block
- MOVE.L (A4),D3 ; get the mouse point
- ;
- LEA BRect(A4),A2 ; get pointer to boundsRect
- MOVE.L A2,A1 ; get pointer in A1
- BSR GetCtlRect ; copy control bounds rect
- ;
- MOVE.L A2,A0 ; point to boundsRect
- BSR TestHV ; get h/v selector in D0
- MOVE D2,-(SP) ; preserve D2
- SWAP D2
- MOVE.W #$FFE8,D2 ; get inset factor (24 pixels hyst)
- MOVE D0,D4 ; keep selector in D4
- BEQ.S @1 ; if vertical, we're cool
- SWAP D2 ; adjust inset factor
- BRA.S @2
- ;
- @1 SWAP D3 ; adjust mouse pt
- ;
- @2 MOVE.L A2,-(SP) ; push pointer to rectangle
- MOVE.L D2,-(SP) ; push inset factor
- _InsetRect ; go inset it
- ;
- ; build the slopRect by insetting the boundsRect
- ;
- LEA SRect(A4),A0 ; get slopRect pointer
- MOVE.L (A4),(A0) ; copy boundsRect into slopRect
- MOVE.L 4(A4),4(A0) ; copy botRight, too
- ;
- MOVE.L #$FF800000,D0 ; get inset factor (assume vertical)
- TST D4 ; which dimension
- BEQ.S @3 ; if vertical, we're cool
- SWAP D0
- ;
- @3 MOVE.L A0,-(SP) ; push slopRect pointer
- MOVE.L D0,-(SP) ; push inset factor
- _InsetRect ; inset it
- ;
- ; now further adjust the boundsRect depending where the mousePt is relative to the
- ; indicator box.
- ;
- MOVE.L (A3),A0 ; get control pointer
- MOVE.L ContrlData(A0),A0 ; get region handle
- MOVE.L (A0),A0 ; get region pointer
- SUB RgnBBox(A0,D4),D3 ; subtract relevant coordinate
- ADD D3,Top(A2,D4) ; offset logical top
- ;
- ; fix up logical bottom, too
- ;
- MOVE (SP)+,D2 ; get back D2
- SUBQ #1,D2
- SUB D2,Bottom(A2,D4)
- ADD D3,Bottom(A2,D4) ; subtract (15-number) from bottom
- ;
- ; now set up axis parameter
- ;
- LSR #1,D4 ; divide by 2
- EOR #1,D4 ; flip the sense
- ADDQ #1,D4 ; add increment
- MOVE D4,TAxis(A4) ; to derive axis parameter
- RTS
-
-
- END